package com.qiaofang.applet.rest;

import com.alibaba.fastjson.JSONObject;
import com.qiaofang.applet.common.client.yxim.model.YxProperties;
import com.qiaofang.applet.common.dto.DataResponse;
import com.qiaofang.applet.common.exception.BusinessException;
import com.qiaofang.applet.service.other.domain.CityCompany;
import com.qiaofang.applet.service.other.domain.Corporation;
import com.qiaofang.applet.service.other.domain.YxImUser;
import com.qiaofang.applet.service.other.service.CityCompanyService;
import com.qiaofang.applet.service.other.service.CorporationService;
import com.qiaofang.applet.service.other.service.YxImMessageService;
import com.qiaofang.applet.service.other.service.YxImUserService;
import com.qiaofang.applet.service.other.service.dto.AccidsQueryDto;
import com.qiaofang.applet.service.other.service.dto.YxImUserDTO;
import com.qiaofang.applet.service.other.service.dto.YxImUserExternalDto;
import com.qiaofang.applet.service.other.service.dto.YxImUserReqDTO;
import com.qiaofang.applet.service.property.service.dto.IdDto;
import io.micrometer.core.instrument.util.IOUtils;
import io.micrometer.core.instrument.util.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * 网易云信im
 *
 * @author junze.liu
 */
@Slf4j
@RestController
@RequestMapping("/api/web/yxIm")
@Api(tags = "网易云信IM")
public class YxImController {

    @Autowired
    private YxImUserService yxImUserService;

    @Autowired
    private YxImMessageService yxImMessageService;

    @Autowired
    private CityCompanyService cityCompanyService;

    @Autowired
    private CorporationService corporationService;

    @Value("${yxim.appServer}")
    public String appServer;

    @Value("${yxim.appKey}")
    public String appKey;

    @Value("${yxim.appSecret}")
    public String appSecret;

    @PostMapping(value = "/getYxIMTokenByLogin")
    @ApiOperation(value = "登录时获取网易云信token", notes = "token为空时，不会创建token")
    public DataResponse<YxImUserDTO> getYxIMTokenByLogin(@RequestBody @Valid YxImUserReqDTO reqDTO) {
        log.info("getYxIMToken reqDTO ==> {}", JSONObject.toJSONString(reqDTO));
        //查询im用户信息
        YxImUserDTO resDto = yxImUserService.getYxImUserByDto(reqDTO);
        return DataResponse.ok(resDto);
    }

    @PostMapping(value = "/getYxIMToken")
    @ApiOperation(value = "获取网易云信token", notes = "获取网易云信token")
    public DataResponse<List<YxImUserDTO>> getYxIMToken(@RequestBody @Valid List<YxImUserReqDTO> reqList) {
        log.info("getYxIMToken reqDTO ==> {}", JSONObject.toJSONString(reqList));
        List<YxImUserDTO> resList = new ArrayList<>(2);
        for (YxImUserReqDTO reqDTO : reqList) {
            //查询im用户信息
            YxImUserDTO resDto = yxImUserService.getYxImUserByDto(reqDTO);
            if (resDto != null) {
                resList.add(resDto);
                continue;
            }
            //设置云信im配置字段
            YxProperties config = new YxProperties();
            config.setAppServer(appServer);
            config.setAppKey(appKey);
            config.setAppSecret(appSecret);
            //未查询到时，创建新的im用户信息
            resDto = yxImUserService.createYxIm(reqDTO, config);
            resList.add(resDto);
        }
        return DataResponse.ok(resList);
    }

    @PostMapping(value = "/external/getYxIMToken")
    @ApiOperation(value = "获取网易云信token（外部平台调用）", notes = "获取网易云信token（外部平台调用）")
    public DataResponse<List<YxImUserDTO>> getYxIMToken(@RequestBody YxImUserExternalDto reqDto) {
        log.info("getYxIMToken reqDTO ==> {}", JSONObject.toJSONString(reqDto));
        String companyUuid = reqDto.getCompanyUuid();
        //判断当前公司是否开通云信服务
        CityCompany company = cityCompanyService.getCompanyByUuid(companyUuid);
        if (company == null || company.getStatus() == 0){
            log.error("该公司在小程序端不存在或已被禁用,companyUuid:{}", companyUuid);
            throw new BusinessException("该公司在小程序端不存在或已被禁用");
        }
        String corporationCode = company.getCorporationCode();
        Corporation corporation = corporationService.getCorporationByCorporationCode(corporationCode);
        if (corporation == null || corporation.getDeleted()){
            log.error("该公司所在集团在小程序端不存在或已被禁用,companyUuid:{},corporationCode:{}", companyUuid, corporationCode);
            throw new BusinessException("该公司所在集团在小程序端不存在或已被禁用");
        }
        String prefix = corporation.getAccidPrefix();
        if (StringUtils.isEmpty(prefix) || !prefix.contains("-")){
            log.error("该公司所在集团未配置云信IM账号前缀,corporationCode:{}", corporationCode);
            throw new BusinessException("该公司所在集团未配置云信IM账号前缀");
        }
        List<YxImUserDTO> resList = new ArrayList<>(2);
        List<String> empUuidList = reqDto.getEmpUuidList();

        for (String empUuid : empUuidList) {
            if (!empUuid.contains(companyUuid)){
                empUuid = companyUuid + "_" + empUuid;
            }
            YxImUserReqDTO reqDTO = new YxImUserReqDTO(empUuid, "2");
            //查询im用户信息
            YxImUserDTO resDto = yxImUserService.getYxImUserByDto(reqDTO);
            if (resDto != null) {
                resList.add(resDto);
                continue;
            }
            //设置云信im配置字段
            YxProperties config = new YxProperties();
            config.setAppServer(appServer);
            config.setAppKey(appKey);
            config.setAppSecret(appSecret);
            //未查询到时，创建新的im用户信息
            resDto = yxImUserService.createYxIm(reqDTO, config);
            resList.add(resDto);
        }
        return DataResponse.ok(resList);
    }

    @PostMapping(value = "/receiveMsg")
    @ApiOperation(value = "网易云信消息抄送接口", notes = "网易云信消息抄送接口")
    public void receiveMsg(HttpServletRequest request, HttpServletResponse response) {
        JSONObject result = new JSONObject();
        try {
            String receiveMsg = IOUtils.toString(request.getInputStream(), Charset.forName("UTF-8"));
            log.info("网易云信消息抄送接口 receiveMsg ==> {}", receiveMsg);
            //返回消息接收成功信息给网易云信
            result.put("code", 200);
            response.getWriter().write(result.toString());
            //保存消息
            yxImMessageService.saveByReceiveMsg(receiveMsg);
        } catch (IOException e) {
            log.error("网易云信消息抄送接口error", e);
        }
    }


    @PostMapping(value = "/getUserIdByAccid")
    @ApiOperation(value = "根据accid得到userId", notes = "根据accid得到userId")
    public DataResponse<String> getUserIdByAccid(@RequestBody @Valid IdDto idDto) {
        String userId = null;
        YxImUser yxImUser = yxImUserService.findByAccidAndUserType(idDto.getId(), "2");
        if (yxImUser != null) {
            userId = yxImUser.getUserId();
        }
        return DataResponse.ok(userId);
    }

    @PostMapping(value = "/getYxUserInfoList")
    @ApiOperation(value = "获取网易云信用户列表", notes = "获取网易云信用户列表")
    public DataResponse<List<YxImUserDTO>> getYxUserInfoList(@RequestBody @Valid AccidsQueryDto accidsQueryDto) {
        return DataResponse.ok(yxImUserService.getYxUserInfoList(accidsQueryDto));
    }
}
